home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cdrtools-1.10 / libfile / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-06  |  6.6 KB  |  282 lines

  1. /*
  2. **    find file types by using a modified "magic" file
  3. **
  4. **    based on file v3.22 by Ian F. Darwin (see below)
  5. **
  6. **    For each entry in the magic file, the message MUST start with
  7. **    two 4 character strings which are the CREATOR and TYPE for the
  8. **    Mac file. Any continuation lines are ignored. e.g magic entry
  9. **    for a GIF file:
  10. **    
  11. **    0       string          GIF8            8BIM GIFf
  12. **    >4      string          7a              \b, version 8%s,
  13. **    >4      string          9a              \b, version 8%s,
  14. **    >6      leshort         >0              %hd x
  15. **    >8      leshort         >0              %hd,
  16. **    #>10    byte            &0x80           color mapped,
  17. **    #>10    byte&0x07       =0x00           2 colors
  18. **    #>10    byte&0x07       =0x01           4 colors
  19. **    #>10    byte&0x07       =0x02           8 colors
  20. **    #>10    byte&0x07       =0x03           16 colors
  21. **    #>10    byte&0x07       =0x04           32 colors
  22. **    #>10    byte&0x07       =0x05           64 colors
  23. **    #>10    byte&0x07       =0x06           128 colors
  24. **    #>10    byte&0x07       =0x07           256 colors
  25. **
  26. **    Just the "8BIM" "GIFf" will be used whatever the type GIF file
  27. **    it is.
  28. **
  29. **    Modified for mkhybrid James Pearson 19/5/98
  30. */
  31.  
  32. /*
  33.  * file - find type of a file or files - main program.
  34.  *
  35.  * Copyright (c) Ian F. Darwin, 1987.
  36.  * Written by Ian F. Darwin.
  37.  *
  38.  * This software is not subject to any license of the American Telephone
  39.  * and Telegraph Company or of the Regents of the University of California.
  40.  *
  41.  * Permission is granted to anyone to use this software for any purpose on
  42.  * any computer system, and to alter it and redistribute it freely, subject
  43.  * to the following restrictions:
  44.  *
  45.  * 1. The author is not responsible for the consequences of use of this
  46.  *    software, no matter how awful, even if they arise from flaws in it.
  47.  *
  48.  * 2. The origin of this software must not be misrepresented, either by
  49.  *    explicit claim or by omission.  Since few users ever read sources,
  50.  *    credits must appear in the documentation.
  51.  *
  52.  * 3. Altered versions must be plainly marked as such, and must not be
  53.  *    misrepresented as being the original software.  Since few users
  54.  *    ever read sources, credits must appear in the documentation.
  55.  *
  56.  * 4. This notice may not be removed or altered.
  57.  */
  58. #ifndef    lint
  59. static char *moduleid = 
  60.     "@(#)$Id: file.c,v 1.38 1997/01/15 19:28:35 christos Exp $";
  61. #endif    /* lint */
  62.  
  63. #include <mconfig.h>
  64. #include <stdio.h>
  65. #include <stdxlib.h>
  66. #include <strdefs.h>
  67. #include <sys/types.h>
  68. #include <sys/param.h>    /* for MAXPATHLEN */
  69. #include <sys/stat.h>
  70. #include <fcntl.h>    /* for open() */
  71. #if (__COHERENT__ >= 0x420)
  72. # include <sys/utime.h>
  73. #else
  74. # ifdef USE_UTIMES
  75. #  include <sys/time.h>
  76. # else
  77. #  include <utime.h>
  78. # endif
  79. #endif
  80. #include <unistd.h>    /* for read() */
  81.  
  82. #include <netinet/in.h>        /* for byte swapping */
  83.  
  84. #include "patchlevel.h"
  85. #include "file.h"
  86.  
  87. int             /* Global command-line options         */
  88. #ifdef DEBUG
  89.     debug = 1,     /* debugging                 */
  90. #else
  91.     debug = 0,     /* debugging                 */
  92. #endif /* DEBUG */
  93.     lflag = 0,    /* follow Symlinks (BSD only)         */
  94.     zflag = 0;    /* follow (uncompress) compressed files */
  95.  
  96. int            /* Misc globals                */
  97.     nmagic = 0;    /* number of valid magic[]s         */
  98.  
  99. struct  magic *magic;    /* array of magic entries        */
  100.  
  101. char *magicfile;    /* where magic be found         */
  102.  
  103. char *progname;        /* used throughout             */
  104. int lineno;        /* line number in the magic file    */
  105.  
  106. char *    get_magic_match    __PR((const char *inname));
  107. void    clean_magic    __PR((void));
  108.  
  109. #if 0
  110. static int    byteconv4    __P((int, int, int));
  111. static short    byteconv2    __P((int, int, int));
  112. #endif
  113.  
  114. #if 0
  115. /*
  116.  * byteconv4
  117.  * Input:
  118.  *    from        4 byte quantity to convert
  119.  *    same        whether to perform byte swapping
  120.  *    big_endian    whether we are a big endian host
  121.  */
  122. static int
  123. byteconv4(from, same, big_endian)
  124.     int from;
  125.     int same;
  126.     int big_endian;
  127. {
  128.   if (same)
  129.     return from;
  130.   else if (big_endian)        /* lsb -> msb conversion on msb */
  131.   {
  132.     union {
  133.       int i;
  134.       char c[4];
  135.     } retval, tmpval;
  136.  
  137.     tmpval.i = from;
  138.     retval.c[0] = tmpval.c[3];
  139.     retval.c[1] = tmpval.c[2];
  140.     retval.c[2] = tmpval.c[1];
  141.     retval.c[3] = tmpval.c[0];
  142.  
  143.     return retval.i;
  144.   }
  145.   else
  146.     return ntohl(from);        /* msb -> lsb conversion on lsb */
  147. }
  148.  
  149. /*
  150.  * byteconv2
  151.  * Same as byteconv4, but for shorts
  152.  */
  153. static short
  154. byteconv2(from, same, big_endian)
  155.     int from;
  156.     int same;
  157.     int big_endian;
  158. {
  159.   if (same)
  160.     return from;
  161.   else if (big_endian)        /* lsb -> msb conversion on msb */
  162.   {
  163.     union {
  164.       short s;
  165.       char c[2];
  166.     } retval, tmpval;
  167.  
  168.     tmpval.s = (short) from;
  169.     retval.c[0] = tmpval.c[1];
  170.     retval.c[1] = tmpval.c[0];
  171.  
  172.     return retval.s;
  173.   }
  174.   else
  175.     return ntohs(from);        /* msb -> lsb conversion on lsb */
  176. }
  177. #endif
  178.  
  179. /*
  180.  * get_magic_match - get the CREATOR/TYPE string
  181.  * based on the original process()
  182.  */
  183. char *
  184. get_magic_match(inname)
  185. const char    *inname;
  186. {
  187.     int    fd = 0;
  188.     unsigned char    buf[HOWMANY+1];    /* one extra for terminating '\0' */
  189.     struct stat    sb;
  190.     int nbytes = 0;    /* number of bytes read from a datafile */
  191.     char *match;
  192.  
  193.     /* check the file is regular and non-zero length */
  194.     if (stat(inname, &sb) != 0)
  195.         return 0;
  196.  
  197.     if (sb.st_size == 0 || ! S_ISREG(sb.st_mode))
  198.         return 0;
  199.  
  200.     if ((fd = open(inname, O_RDONLY)) < 0)
  201.             return 0;
  202.  
  203.     /*
  204.      * try looking at the first HOWMANY bytes
  205.      */
  206.     if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1)
  207.         return 0;
  208.  
  209.     if (nbytes == 0)
  210.         return 0;
  211.     else {
  212.         buf[nbytes++] = '\0';    /* null-terminate it */
  213.         match = softmagic(buf, nbytes);
  214.     }
  215.  
  216. #ifdef RESTORE_TIME
  217.     /* really no point as we going to access the file later anyway */
  218.     {
  219.         /*
  220.          * Try to restore access, modification times if read it.
  221.          */
  222. # ifdef USE_UTIMES
  223.         struct timeval  utsbuf[2];
  224.         utsbuf[0].tv_sec = sb.st_atime;
  225.         utsbuf[1].tv_sec = sb.st_mtime;
  226.  
  227.         (void) utimes(inname, utsbuf); /* don't care if loses */
  228. # else
  229.         struct utimbuf  utbuf;
  230.  
  231.         utbuf.actime = sb.st_atime;
  232.         utbuf.modtime = sb.st_mtime;
  233.         (void) utime(inname, &utbuf); /* don't care if loses */
  234. # endif
  235. #endif
  236.     (void) close(fd);
  237.  
  238.     return(match);
  239. }
  240.  
  241. /*
  242.  * clean_magic - deallocate memory used
  243.  */
  244. void
  245. clean_magic()
  246. {
  247.     if (magic)
  248.         free(magic);
  249. }
  250.     
  251.  
  252. #ifdef MAIN
  253. main(argc, argv)
  254. int    argc;
  255. char    **argv;
  256. {
  257.     char    *ret;
  258.     char    creator[5];
  259.     char    type[5];
  260.  
  261.     if (argc < 3)
  262.         exit(1);
  263.  
  264.     init_magic(argv[1]);
  265.  
  266.     ret = get_magic_match(argv[2]);
  267.  
  268.     if (!ret)
  269.         ret = "unixTEXT";
  270.  
  271.     sscanf(ret, "%4s%4s", creator, type);
  272.  
  273.     creator[4] = type[4] = '\0';
  274.  
  275.     printf("%s %s\n", creator, type);
  276.  
  277.  
  278.     exit(0);
  279. }
  280. #endif /* MAIN */
  281.  
  282.